
package andre.grids.network;

import andre.grids.filesystem.common.DirectoryOperations;
import andre.grids.filesystem.common.FileOperations;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import andre.grids.filesystem.server.configuration.*;
import andre.grids.filesystem.server.filemanagement.FileSystemOperationsImpl;

/**
 *
 * @author andre
 */
public class PeerObjects {
    
    private DirectoryOperations directory;
    private FileOperations file;
    private String hostName;
    private boolean isFileServer;
    private int serverPort;
    
    public PeerObjects(String hostName, boolean isFileServer, int port) {
        serverPort = port;
        this.hostName = hostName;
        this.isFileServer = isFileServer;
        
        try {
            loadObjects(hostName,isFileServer);
        } catch(Exception e)
        {
            directory = null;
            file = null;
        }
        
    }
    
    public PeerObjects(String hostName, boolean isFileServer) {
        this(hostName,isFileServer,
                Integer.parseInt(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_PORT_NUMBER)));
    }
    
    public PeerObjects(String hostName) {
        this(hostName,false);
    }
    
    public PeerObjects(String hostName, int port) {
        this(hostName,false,port);
    }
    
    public String getHost() {
        return this.hostName;
    }

    public DirectoryOperations getDirectory() {
        try {
        if (directory == null)
            loadObjects(hostName,isFileServer);
        }
        catch(Exception e) {
            andre.grids.util.log.Log.logException(e, this);
            directory = null;
        }
        return directory;
    }

    public FileOperations getFile() {
        try {
        if (file == null)
            loadObjects(hostName,isFileServer);
        }
        catch(Exception e) {
            andre.grids.util.log.Log.logException(e, this);
            file = null;
        }
        return file;
    }
    
    public boolean isLocal() {
        return this.hostName.equals(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HOST_NAME));
    }
    
    private void loadObjects(String hostName) throws RemoteException, NotBoundException, AccessException
    {
        Registry reg = LocateRegistry.getRegistry(hostName, serverPort);
        
//        if (hostName.equalsIgnoreCase(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HOST_NAME)))
//            file = RmiRegister.getLocalFileOperations();
//        else
//            file = (FileOperations)reg.lookup(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_FILEOPS_RMI_BIND_NAME));
        
        if (hostName.equalsIgnoreCase(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HOST_NAME)))
            directory = RmiRegister.getLocalDirectoryOperation();
        else
            directory = (DirectoryOperations)reg.lookup(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_DIROPS_RMI_BIND_NAME));
        
        reg = null;
        
    }
    
    private void loadObjects(String hostName, boolean onlyFile) throws RemoteException, NotBoundException, AccessException {
        if (onlyFile) {
            int port = Integer.parseInt(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_PORT_NUMBER));
            Registry reg = LocateRegistry.getRegistry(hostName, port);

            if (hostName.equalsIgnoreCase(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_HOST_NAME)))
                file = RmiRegister.getLocalFileOperations();
            else
                file = (FileOperations)reg.lookup(ConfigurationManager.getBaseConfigInstance().getValue(ServerConfigurationProps.SERVER_FILEOPS_RMI_BIND_NAME));        
        } else
            loadObjects(hostName);
    }
    
    public void release()
    {
        directory = null;
        file = null;
        System.gc();
    }

    @Override
    protected void finalize() throws Throwable {
        release();
        super.finalize();
    }
    
}
